#!/usr/bin/env python
# encoding: utf-8


"""
@file: sanjiao_utils.py
@time: 2016/10/21 上午11:16
"""
from io import StringIO
from functools import reduce
from sympy import cancel, fraction, sin, cos, tan, cot, expand_trig, expand, ceiling, floor, symbols, Abs
from sympy.core.numbers import ComplexInfinity
from sympy.core.mul import Mul
from mathsolver.functions.root.jiefangchenzu import *
from mathsolver.functions.budengshi import common_opers as co
from mathsolver.functions.sanjiao.trigsimplify import TrigSimplify
import re
import sys
from mathsolver.functions.sanjiao.sanjiaofangcheng import JieSanJiaoFangCheng
from operator import itemgetter
from mathsolver.functions.sanjiao import Jiao


def is_trig_f(f):
    """
    是否三角函数表达式
    :param f: 
    :return: 
    """
    from sympy.functions.elementary.trigonometric import TrigonometricFunction
    from sympy.functions.elementary.hyperbolic import HyperbolicFunction
    f = sympify(f)
    return f.has(TrigonometricFunction) or f.has(HyperbolicFunction)


def derivation(conds, formulas):
    """
    根据提供的公式，自动推导
    :param conds: 条件
    :param formulas: 变量公式，公式之间要形成闭关，也就是有一条循环路线。
    :return: 5个变量的值
    """
    steps = []  # 推导过程
    conds_queue = list(conds.items())  # 条件队列
    vars_queue = [(k, v) for k, v in formulas.items() if k not in conds]  # 变量队列
    d_times = 0
    max_try_time = 2 * len(conds_queue) + len(vars_queue)
    while vars_queue:
        if d_times > max_try_time:
            raise Exception('Please write complete rules')  # 填写完备的规则，公式之间要形成闭环
        var_name, var_exprs = vars_queue.pop()
        for v_e in var_exprs:
            v_e = sympify(v_e)
            v_e_v = v_e.subs(conds_queue)
            if v_e_v.is_real:  # 如果计算出变量值
                conds_queue.append((var_name, simplify(v_e_v)))
                steps.append((var_name, v_e, simplify(v_e_v)))
                break
        else:
            vars_queue.insert(0, (var_name, var_exprs))
        d_times += 1

    return dict(conds_queue), steps


def trig_simp(trig_e):
    """
    三角函数化简.返回化简结果和步骤
    :param trig_e: 三角函数
    :return:
    >>> trig_simp('sin(x)**4-cos(y)**2+sin(y)**2+2*cos(x)**2')[0]
    sin(x)**4 - 2*sin(x)**2 + 2*sin(y)**2 + 1
    """
    stdout = sys.stdout
    temp_out = StringIO()
    sys.stdout = temp_out
    try:
        TrigSimplify().solver(BaseEq([trig_e, '0']))
    except Exception:
        sys.stdout = stdout
        return trig_e, []
    sys.stdout = stdout
    steps_print = temp_out.getvalue()
    result = steps_print[steps_print.find(':') + 1:].strip()
    steps = steps_print.split('\n')[1:-2]
    steps = map(lambda s: s.split('=')[1].strip(), steps)
    latex_steps = []
    for step in steps:
        try:
            latex_step = new_latex(sympify(step))
        except Exception:
            latex_step = new_latex(sympify(step[:step.rfind('(')]))
        latex_steps.append(latex_step)
    return sympify(result), latex_steps


def trig_coeff(trig_e):
    """
    三角函数的系数
    :param trig_e:
    :return:
    >>> trig_coeff('3*sin(5*x)')
    3
    >>> trig_coeff('-sqrt(3)*sin(a)/2')
    -sqrt(3)/2
    """
    trig_e = sympify(trig_e)
    # coeff = trig_e.as_coefficients_dict().values()[0]
    # pm = abs(coeff) / coeff
    # trig_e_2 = trig_e ** 2
    # coeff2 = trig_e_2.as_coefficients_dict().values()[0]
    # last_coeff = sqrt(coeff2) * pm
    # return last_coeff
    args = sympify(trig_e.args)
    if len(args) == 1:
        return 1
    else:
        return reduce(lambda a, b: a * b, args[:-1])


# print trig_coeff('sqrt(2)*x')


def trig_coefficients_dict(trig_e):
    """
    含有三角函数的表达式的coefficients_dict. sympy自带的as_coefficients_dict()有问题
    :param trig_e:
    :return:
    >>> trig_coefficients_dict('-sqrt(3)*sin(a)/2 + sqrt(3)/2*cos(a)')
    {sin(a): -sqrt(3)/2, 1: 0, cos(a): sqrt(3)/2}
    """
    symoms, const = co.symoms_and_const(sympify(trig_e))
    c_d = {}
    for mo in symoms:
        c = trig_coeff(mo)
        m = mo / c
        c_d[m] = c
    c_d[sympify('1')] = const
    return c_d


def trig_eq_std(trig_eq):
    """
    三角函数等式的标准化, 左边为表达式，右边为常数
    :param trig_eq: 三角函数的等式
    :return:
    >>> trig_eq_std(BaseEq(['cos(a + pi/6) -3*sqrt(3)/5- sin(a)', '0'])).sympify()
    [-sin(a) + cos(a + pi/6), 3*sqrt(3)/5]
    """
    l, r = trig_eq.sympify()
    f = l - r
    symoms, const = co.symoms_and_const(f)
    nl = reduce(lambda a, b: a + b, symoms)
    nr = -const
    if nr < 0:
        nr = -nr
        nl = - nl
    return BaseEq([nl, nr])


def trig_raded(trig_f, x_symbol='x'):
    """
    三角函数弧度制化
    :param trig_f:
    :param x_symbol:
    :return:
    >>> trig_raded('3*sin(2*x + 70)')
    3*sin(2*x + 7*pi/18)
    >>> trig_raded('3*sin(x + 30)')
    3*sin(x + pi/6)
    >>> trig_raded('3*sin(x + pi/6)')
    3*sin(x + pi/6)
    """
    f = sympify(trig_f)
    c = trig_coeff(trig_f)
    m = f / c
    arg = m.args[0]
    symons, const = co.symoms_and_const(arg)
    symons = reduce(lambda a, b: a * b, symons)
    if not const.args:  # 如果是常数
        const = const / 180 * pi
    return type(m)(symons + const) * c


def trig_arg(trig_f):
    """
    三角函数里面的参数
    :param trig_f:
    :return:
    >>> trig_arg('3*sin(2*x + pi)')
    2*x
    >>> trig_arg('3*cot(x + pi)')
    x
    """
    f = sympify(trig_f)
    c = trig_coeff(f)
    m = f / c
    return m.args[0]


def trig_type(trig_f):
    """
    三角函数的类型
    :param trig_f:
    :return:
    >>> trig_type('4*sin(2*x + 3)')
    sin
    """
    trig_f = sympify(trig_f)
    coef = trig_coeff(trig_f)
    trig_mon = trig_f / coef
    return type(trig_mon)


def f_subs(p, s, r):
    """
    替换掉正则表达式匹配的值
    :param p:
    :param s:
    :param r:
    :return:
    """
    s = sympify(s)
    g = re.findall(p, str(s))
    for a in g:
        s = s.subs(a, r)
    return s


def quad_func_domain(f, intl, x_symbol='x'):
    """
    二次函数的值域
    :param f:
    :param intl: 定义域
    :param x_symbol:
    :return:
    """
    f = sympify(f)
    symb = sympify(x_symbol)
    sf, op_point = co.top_point_expr(f, x_symbol=str(x_symbol))
    _, op_value = op_point
    lv = sf.subs(symb, intl.left)
    rv = sf.subs(symb, intl.right)
    if op_point[0] in intl:
        op_value = op_point[1]
        min_v = min(lv, rv, op_value)
        max_v = max(lv, rv, op_value)

    else:
        min_v = min(lv, rv)
        max_v = max(lv, rv)
    return Interval(min_v, max_v)


def fraced(f):
    """
    是否是一个分式
    :param f:
    :return:
    """
    mo, de = fraction(cancel(f))
    return not de.is_real


def to_seg_func(seg_fs, x_symbol='x'):
    """
    转换成分段函数
    :param seg_fs:
    :param x_symbol:
    :return:
    """
    func = {'var': str(x_symbol), 'expression': [], 'type': '', 'name': 'f'}
    for f, i in seg_fs:
        dt = {'main': str(f), 'equality': [], 'belong': [], 'inequality': []}
        dt['inequality'].append(co.to_ineq_expr_list(co.print_interval(i, x_symbol)))
        func['expression'].append(dt)
    #
    basef = BaseFunc(func)
    return basef


def std_simp_trig_eq(f):
    """
    三角函数表达式标准化
    :param f:
    :return:
    """
    f = sympify(f)
    l, r = trig_eq_std(BaseEq([f, '0'])).sympify()
    if isinstance(l, Add):
        return BaseEq([l, r])
    c = trig_coeff(l)
    n_l, n_r = l / c, r / c
    return BaseEq([n_l, n_r])


def trig_subs(f):
    """
    三角函数替换 sin:A,cos:C, tan:T
    :param f:
    :return:
    """
    sin_p = r'sin\(.*?\)'  # A
    f = f_subs(sin_p, f, 'A')
    cos_p = r'cos\(.*?\)'  # C
    f = f_subs(cos_p, f, 'C')
    tan_p = r'tan\(.*?\)'  # T
    f = f_subs(tan_p, f, 'T')
    cot_p = r'cot\(.*?\)'
    f = f_subs(cot_p, f, 'B')
    return f


def expand_tan_cot(f):
    """
    展开tan 或者 cot
    :param f:
    :return:
    >>> expand_tan_cot('tan(x + pi/3)')
    -(tan(x) + sqrt(3))/(sqrt(3)*tan(x) - 1)
    >>> expand_tan_cot('tan(x)')
    tan(x)
    """
    f = simplify(f)
    c = trig_coeff(f)
    m = f / c
    coted = False
    if isinstance(m, cot):
        coted = True
    arg_p = r'\((.*?)\)'
    arg = sympify(re.search(arg_p, str(m)).groups()[0])
    if isinstance(arg, Symbol):
        return c * tan(arg) if not coted else c / tan(arg)
    elif isinstance(arg, Mul) and co.mo_coeff(arg) == 2:  # tan(2*x), cot(2*x) = 1/tan(2*x)
        n_f = 2 * tan(arg / 2) / (1 - tan(arg / 2) ** 2)
        return simplify(c * n_f if not coted else c / n_f)
    elif isinstance(arg, Add) and len(arg.as_coefficients_dict().items()) == 2:
        arg0, arg1 = co.symoms_and_const(arg)
        arg0 = arg0[0]
        mo = (sympify(tan(arg0)) + sympify(tan(arg1)))
        de = (sympify('1') - sympify(tan(arg0)) * sympify(tan(arg1)))
        n_f = mo / de
        return simplify(c * n_f if not coted else c / n_f)
    else:
        return f


def trig_simped(trig_f):
    """
    三角函数是否已经化简完毕。   形如 y = k*f(w*x + b) + c 其中 f in (sin, cos, tan, cot)
    :param trig_f: 三角函数
    :return: 是否已经化简完毕
    """
    trig_f = sympify(trig_f)
    if trig_f.is_real:
        return True
    trig_mons, _ = co.split_mons_const(trig_f)
    if len(co.coefficients_dict(trig_mons)) > 1:
        return False
    coef = trig_coeff(trig_mons)
    trig_f = trig_mons / coef
    if type(trig_f) in (sin, cos, tan, cot):
        return True
    else:
        return False


def segment_absed_poly(poly_f):
    """
    将含有绝对值的多项式转变成分段函数
    :param poly_f:
    :return:
    """

    class AbsMon(object):
        def __init__(self, coef, arg):
            self.coef = coef
            self.arg = arg

        def to_sympy(self):
            return sympify(self.coef) * Abs(self.arg)

    class AbsMonArgPM(object):  # 绝对值表达式中参数的正负
        def __init__(self, abs_mon, positive):
            self.abs_mon = abs_mon
            self.positive = positive

        def abs_arg_ineq(self):
            if self.positive:
                return str(self.abs_mon.arg) + '>0'
            else:
                return str(self.abs_mon.arg) + '<0'

        def remove_abs_op(self):  # 去掉绝对值符号
            if self.positive:
                return self.abs_mon.coef * self.abs_mon.arg
            else:
                return - self.abs_mon.coef * self.abs_mon.arg

    def join_abs_mons(abs_mon_argpms):  # 联合绝对值表达式
        f = sympify('0')
        intl = S.Reals
        for m in abs_mon_argpms:
            f += m.remove_abs_op()
            intl = intl.intersect(solveset(m.abs_arg_ineq(), domain=S.Reals))
        return f, intl

    coefs_d = co.coefficients_dict(poly_f)
    absed_mons = filter(lambda t: isinstance(t[0], Abs), coefs_d.items())
    other_mons = sympify(poly_f) - reduce(lambda a, b: a + b, map(lambda t: t[0] * t[1], absed_mons))
    absed_mons = map(lambda m: AbsMon(m[1], m[0].args[0]), absed_mons)
    absed_mons_arg_pms = map(lambda m: (AbsMonArgPM(m, True), AbsMonArgPM(m, False)), absed_mons)
    fs = co.combin_iters(*absed_mons_arg_pms)
    segfs = filter(lambda t: not isinstance(t[1], EmptySet), map(join_abs_mons, fs))
    segfs = map(lambda seg: (seg[0] + other_mons, seg[1]), segfs)
    return segfs


# print segment_absed_poly('Abs(sin(x)) - Abs(cos(x))')
# print segment_absed_poly('Abs(2*x + 3) + Abs(x - 5) - Abs(3*x - 7) + 2*x')
# print segment_absed_poly('3*sin(x) + Abs(sin(x))')

def aux_ang_f(f):  # 辅助角公式 a*sin(x) + b*cos(x) = sqrt(a**2 + b**2)*sin(x+theta) tan(theta) = b/a
    # sin(x)/2 + sqrt(3)*cos(x)
    symb = list(sympify(f).free_symbols)[0]
    simp_f, _ = trig_simp(f)
    trig_f, const = co.split_mons_const(simp_f)
    if simp_f != f:
        sin_arg = (simp_f / trig_coeff(simp_f)).args[0]
        _, angle_value = co.split_mons_const(sin_arg)
        return simp_f, tan(angle_value)
    sined = False
    sin_mon = None
    cosed = False
    cos_mon = None
    for m, c in co.coefficients_dict(trig_f).items():
        if isinstance(m, sin):
            sined = True
            sin_mon = c * m
        elif isinstance(m, cos):
            cosed = True
            cos_mon = c * m
    if sined and cosed:
        a = trig_coeff(sin_mon)
        b = trig_coeff(cos_mon)
        f1 = sqrt(a ** 2 + b ** 2) * sin('%s + theta' % str(symb))
        return f1 + const, b / a
    return f, None


def radianed(f):
    """
    角度值转换为弧度制
    :param f:
    :return:
    """
    f = sympify(f)
    du_p = r'du(\(-?\d+?\))'
    m = re.search(du_p, str(f))
    if m:
        du_str = m.group()
        du_sub = sympify(m.groups()[0]) * pi / 180
        f = f.subs(sympify(du_str), du_sub)
    return f


def expr_trig_mons(e):
    """
    表达式中所有的三角函数 项
    :param e: 
    :return: 
    >>> expr_trig_mons('sin(x/2) + cos(x) + tan(x)')
    ['sin(x/2)', 'cos(x)', 'tan(x)']
    """
    f = sympify(e)
    sin_p = r'sin\(.*?\)'
    cos_p = r'cos\(.*?\)'
    tan_p = r'tan\(.*?\)'
    cot_p = r'cot\(.*?\)'
    single_trig_mons = co.find_reg_expr(sin_p, str(f))
    single_trig_mons.extend(co.find_reg_expr(cos_p, str(f)))
    single_trig_mons.extend(co.find_reg_expr(tan_p, str(f)))
    single_trig_mons.extend(co.find_reg_expr(cot_p, str(f)))
    return single_trig_mons


def trig_func_values(cond_eq):
    """
    根据三角函数的一个条件 计算出其他函数值
    :param cond_eq:
    :return:
    >>> trig_func_values(BaseEq(['cos(x)', '12/13']))
    [[[cos(x), 12/13], [cot(x), -12/5], [sin(x), -5/13], [tan(x), -5/12]], [[cos(x), 12/13], [cot(x), 12/5],
    [sin(x), 5/13], [tan(x), 5/12]]]
    """
    cond_l, cond_r = cond_eq.sympify()
    cond_f = expand_trig(cond_l - cond_r)
    mo, de = co.complete_fraction(cond_f)
    cond_f = mo
    cond_symbs = list(cond_f.free_symbols)
    if len(cond_symbs) != 1:
        raise Exception('Type Match Error')
    cond_symb = cond_symbs[0]
    cond_subs = ((sin(cond_symb), 'SIN'), (cos(cond_symb), 'COS'), (tan(cond_symb), 'TAN'), (cot(cond_symb), 'COT'))
    cond_sub_value = cond_f.subs(cond_subs)
    if not cond_sub_value.is_real:
        return trig_func_values_v2(cond_eq)
    cond_subs = ((sin(cond_symb), 'SIN'), (cos(cond_symb), 'COS'), (tan(cond_symb), 'TAN'), (cot(cond_symb), 'COT'))
    eqs = [['SIN**2 + COS**2', '1']]
    if str(cond_f).find('tan') >= 0:
        eqs.append(['TAN*COS', 'SIN'])
    if str(cond_f).find('cot') >= 0:
        eqs.append(['COT*SIN', 'COS'])
    eqs.append([cond_f.subs(cond_subs), '0'])
    values_list = co.isolve_eqs(BaseEqs(eqs))
    matched = True
    for values in values_list:
        matched = matched and reduce(lambda b1, b2: b1 and b2, map(lambda pair: pair[1].is_real, values))
    if not matched:
        raise Exception('Type Match Error')
    cond_reverse_subs = map(lambda pair: (pair[1], pair[0]), cond_subs)
    new_values_list = []
    for values in values_list:
        tmp_values = map(lambda pair: [pair[0].subs(cond_reverse_subs), pair[1]], values)
        new_values_list.append(tmp_values)
    # 要保证分母不能为0
    new_values_list = filter(lambda _: de.subs(_), new_values_list)
    return new_values_list


def trig_func_values_v2(cond_eq):
    """
    根据三角函数的一个条件 计算出其他函数值
    :param cond_eq:
    :return:
    >>> trig_func_values_v2(BaseEq(['cos(x)', '12/13']))
    [[[cos(x), 12/13], [cot(x), -12/5], [sin(x), -5/13], [tan(x), -5/12]], [[cos(x), 12/13], [cot(x), 12/5],
    [sin(x), 5/13], [tan(x), 5/12]]]
    """
    cond_l, cond_r = cond_eq.sympify()
    cond_f = expand_trig(cond_l - cond_r)
    mo, de = co.complete_fraction(cond_f)
    cond_f = mo
    sin_p = r'sin\(.*?\)'
    cos_p = r'cos\(.*?\)'
    tan_p = r'tan\(.*?\)'
    cot_p = r'cot\(.*?\)'
    single_trig_mons = co.find_reg_expr(sin_p, str(mo))
    single_trig_mons.extend(co.find_reg_expr(cos_p, str(mo)))
    single_trig_mons.extend(co.find_reg_expr(tan_p, str(mo)))
    single_trig_mons.extend(co.find_reg_expr(cot_p, str(mo)))
    trig_mon_args = list(map(lambda _: simp_trig_info(_)[2], single_trig_mons))
    sam_arged = not list(filter(lambda _: _ / trig_mon_args[0] != 1, trig_mon_args))  # 是否所有的参数都是相同的
    if not sam_arged:
        raise Exception('Can Not Calculate')
    cond_symb = trig_mon_args[0]
    cond_subs = ((sin(cond_symb), 'SIN'), (cos(cond_symb), 'COS'), (tan(cond_symb), 'TAN'), (cot(cond_symb), 'COT'))
    eqs = [['SIN**2 + COS**2', '1']]
    if str(cond_f).find('tan') >= 0:  # 如果有tan 在加上 tan的条件
        eqs.append(['TAN*COS', 'SIN'])
    if str(cond_f).find('cot') >= 0:  # # cot 在加上 cot的条件
        eqs.append(['COT*SIN', 'COS'])
    eqs.append([cond_f.subs(cond_subs), '0'])
    # eqs = [['SIN**2 + COS**2', '1'], ['TAN*COS', 'SIN'], ['COT*SIN', 'COS'], [cond_f.subs(cond_subs), '0']]
    # values_list = co.solve_poly_eqs(BaseEqs(eqs))
    values_list = co.isolve_eqs(BaseEqs(eqs))
    # 如果求出来的结果 没有 tan 或者 cot 那么把 tan 和 cot的值加上
    _tmp_values_list = []
    for _values in values_list:
        _tmp_values = [_v for _v in _values]
        if str(cond_f).find('tan') <= 0:  # 如果没有tan则补上
            tan_expr = tan(cond_symb)
            tan_value = sympify('SIN/COS').subs(_values)
            if not isinstance(tan_value, ComplexInfinity):  # 如果求出来的不出复数
                _tmp_values.append((tan_expr, tan_value))
        if str(cond_f).find('cot') <= 0:  # # cot 在加上 cot的条件
            cot_expr = cot(cond_symb)
            cot_value = sympify('COS/SIN').subs(_values)
            if not isinstance(cot_value, ComplexInfinity):  # 如果求出来的不出复数
                _tmp_values.append((cot_expr, cot_value))
        _tmp_values_list.append(_tmp_values)
    values_list = _tmp_values_list
    matched = True
    for values in values_list:
        matched = matched and reduce(lambda b1, b2: b1 and b2, map(lambda pair: pair[1].is_real, values))
    if not matched:
        raise Exception('Type Match Error')
    cond_reverse_subs = list(map(lambda pair: (pair[1], pair[0]), cond_subs))
    new_values_list = []
    for values in values_list:
        tmp_values = list(map(lambda pair: [pair[0].subs(cond_reverse_subs), pair[1]], values))
        new_values_list.append(tmp_values)
    # 要保证分母不能为0
    new_values_list = list(filter(lambda _: de.subs(_), new_values_list))
    return new_values_list


def simp_trig_info(f_str):
    """
    simp_trig_info的改进版， 优化很多bug
    :param f_str: 
    :return: 
    >>> simp_trig_info('3 + 3*cos(4*a - 2*x + pi/4) + (3*a)')
    (3, cos, 4*a - 2*x + pi/4, 3*a + 3)
    >>> simp_trig_info('5 + 2*sin(2*x - pi/3)')
    (2, sin, 2*x - pi/3, 5)
    >>> simp_trig_info('3 + 3*cos((a+3)*x + pi/3) + (3*a)')
    (3, cos, x*(a + 3) + pi/3, 3*a + 3)
    """
    f_expr = sympify(str(f_str))
    sin_terms = co.find_reg_expr(r'sin\(.*?\)', f_str)
    cos_terms = co.find_reg_expr(r'cos\(.*?\)', f_str)
    tan_terms = co.find_reg_expr(r'tan\(.*?\)', f_str)
    cot_terms = co.find_reg_expr(r'cot\(.*?\)', f_str)
    trig_terms = list(co.ichain(sin_terms, cos_terms, tan_terms, cot_terms))
    trig_term = trig_terms[0]
    trig_term = sympify(trig_term)
    coef = f_expr.coeff(trig_term)
    const = f_expr.subs(trig_term, 0)
    t_types = [sin, cos, tan, cot]
    t_type = list(filter(lambda _: str(trig_term).find(str(_)) >= 0, t_types))[0]
    t_arg = sympify(str(trig_term).replace(str(t_type), ''))
    return coef, t_type, t_arg, const


# old
def old_trig_is_simped(cur_expr):
    """
    是否已经处于化简状态.形如A*sin(g(x)) + h 或者 A*cos(g(x)) + h
    :param cur_expr:
    :return:
    """
    cur_expr = sympify(cur_expr)
    if cur_expr.is_real:
        return cur_expr
    coefs_d = co.coefficients_dict(cur_expr)
    if len(coefs_d.items()) > 2:
        return False
    trig_mon, const = co.split_mons_const(cur_expr)
    coef = trig_coeff(trig_mon)
    if str(coef).find('sin') >= 0 or str(coef).find('cos') >= 0 or str(coef).find('tan') >= 0 or str(coef).find(
            'cot') >= 0:
        return False
    trig = trig_mon / coef
    if str(type(trig)) in ['sin', 'cos', 'tan', 'cot']:
        return True
    else:
        return False


def trig_is_simped(cur_expr):
    """
    是否已经处于化简状态.形如A*sin(g(x)) + h 或者 A*cos(g(x)) + h
    :param cur_expr:
    :return:
    """
    try:
        t_coef, t_type, t_arg, t_const = simp_trig_info(cur_expr)
        flag = not is_trig_f(t_coef) and not is_trig_f(t_arg) and not is_trig_f(t_const) and t_type in [sin, cos, tan,
                                                                                                        cot]
    except Exception:
        flag = old_trig_is_simped(cur_expr)
    return flag


def simpled_trig_info(trig_f):
    """
    获取简单三角函数的信息。 系数， 函数类型， 参数， 常数
    :param trig_f:
    :return:
    """
    return simp_trig_info(trig_f)


def stand_trig_ineq(trig_ineq):
    """
    格式化三角函数不等式
    :param trig_ineq:
    :return:
    >>> stand_trig_ineq(BaseIneq(['sin(x)', '<=', 'cos(x) + 1/2'])).sympify()
    (sin(x) - cos(x), '<=', 1/2)
    """
    ineq_l, ineq_op, ineq_r = trig_ineq.sympify()
    trig_f = ineq_l - ineq_r
    trig_mon, const = co.split_mons_const(trig_f)
    return BaseIneq([trig_mon, ineq_op, -const])


def split_symbol_mon(expr, symb='x'):
    """
    切分含有符号变量以及其他
    :param expr:
    :param symb:
    :return:
    """
    expr = expand(sympify(expr))
    d = expr.as_coefficients_dict()
    iterms = d.items()
    symb_mon = sympify('0')
    other_mon = sympify('0')
    for item in iterms:
        mon = item[0] * item[1]
        if str(mon).find(str(symb)) >= 0:
            symb_mon += mon
        else:
            other_mon += mon
    return symb_mon, other_mon


def _simp_param_ineq(ineq_list, x_symbol='x'):
    """
    简单的不等式求解 如 3*x > 2*k + pi
    :param ineq_list:
    :param x_symbol:
    :return:
    """
    l, op, r = sympify(ineq_list[0]), ineq_list[1], sympify(ineq_list[2])
    f = l - r
    x_mon, other_mon = split_symbol_mon(f, x_symbol)
    r = -other_mon
    x_coef = x_mon.coeff(x_symbol)
    r = r / x_coef
    if x_coef < 0:
        op = co.reverse_ineq_op(op)
    return x_symbol, op, r


def solve_param_ineq(ineq_list, x_symbol='x'):
    """
    解三角函数中含参(k)不等式
    :param ineq_list:
    :param x_symbol:
    :return:
    >>> solve_param_ineq(['3*x', '<', '2*k*pi +pi'])
    (-oo, 2*pi*k/3 + pi/3)
    >>> solve_param_ineq(['2*k*pi +3*pi', '>', '3*x', '>=', '2 * k * pi + 2 * pi'])
    [2*pi*k/3 + 2*pi/3, 2*pi*k/3 + pi)
    """
    x_symbol = sympify(x_symbol)
    if len(ineq_list) == 3:
        l, op, r = _simp_param_ineq(ineq_list, x_symbol)
        if op.find('>') >= 0:
            return Interval(r, S.Infinity, left_open=not op.find('=') >= 0)
        else:
            return Interval(-S.Infinity, r, right_open=not op.find('=') >= 0)
    elif len(ineq_list) == 5:
        _, op1, r1 = _simp_param_ineq(ineq_list[:3], x_symbol)
        _, op2, r2 = _simp_param_ineq(ineq_list[2:], x_symbol)
        # l<x<r 或者 l>x>r
        # 如果是   op1 是 > 即 x > r1 那么op2必然是 < 即 x < r2
        # 反之如果 op1 是 < 即 x < r1 那么op2必然是 > 即 x > r2
        if op1.find('>') >= 0:
            return Interval(r1, r2, left_open=not op1.find('=') >= 0, right_open=not op2.find('=') >= 0)
        else:
            return Interval(r2, r1, left_open=not op2.find('=') >= 0, right_open=not op1.find('=') >= 0)
    else:
        raise Exception('illegal inequality express')


def known_trig_eqs(known):
    """
    从三角形中搜出关于三角函数的的等式
    :param known:
    :return:
    """
    if not known:
        return None
    known = dict(filter(lambda _: _[1], known.items()))
    if not known:
        return None
    eqs = []
    for key, value in known.items():
        if co.iterable(value):
            eqs.extend(value)
    # eqs = list(map(lambda kv: (kv[0], list(kv[1])[0] if co.iterable(kv[1]) else kv[1]), list(known.items())))
    arg_eqs = []
    sin_pattern = r'sin\(.*?\)'
    cos_pattern = r'cos\(.*?\)'
    tan_pattern = r'tan\(.*?\)'
    cot_pattern = r'cot\(.*?\)'
    for l_expr, r_expr in eqs:
        try:
            f = sympify(l_expr) - sympify(r_expr)
            sin_mons = co.find_reg_expr(sin_pattern, str(f))
            cos_mons = co.find_reg_expr(cos_pattern, str(f))
            tan_mons = co.find_reg_expr(tan_pattern, str(f))
            cot_mons = co.find_reg_expr(cot_pattern, str(f))
            trig_mons = co.ichain(sin_mons, cos_mons, tan_mons, cot_mons)
            if trig_mons:
                arg_eqs.append([l_expr, r_expr])
        except Exception:
            pass
    if arg_eqs:
        return BaseEqs(arg_eqs)
    else:
        return None


def trig_induction(trig_f):
    """
    三角函数诱导公式
    :param trig_f:
    :return:
    >>> trig_induction('sin(du(150))')
    (1, sin, pi/6, 0)
    >>> trig_induction('sin(2*pi/3)')
    (1, sin, pi/3, 0)
    >>> trig_induction('cos(2*pi/3)')
    (-1, cos, pi/3, 0)
    >>> trig_induction('cos(du(-80))')
    (1, cos, 4*pi/9, 0)
    """
    t_coef, t_type, t_arg, t_const = simp_trig_info(str(trig_f))
    t_arg = radianed(t_arg)
    if t_arg < 0:
        if t_type in [sin, tan, cot]:
            t_arg = -t_arg
            t_coef = -t_coef
        elif t_type == cos:
            t_arg = -t_arg
        else:
            raise Exception('illegality trig')
    if t_arg < pi / 2:
        return t_coef, t_type, t_arg, t_const
    elif pi / 2 < t_arg < pi:
        t_arg = pi - t_arg
        if t_type != sin:
            t_coef = -t_coef
    elif pi < t_arg < 3 * pi / 2:
        t_arg = t_arg - pi
        if t_type == cos:
            t_coef = -t_coef
    elif 3 * pi / 2 < t_arg < 2 * pi:
        t_arg = 2 * pi - t_arg
        if t_type != cos:
            t_coef = -t_coef
    return t_coef, t_type, t_arg, t_const


def print_trig_latex(trig_str):
    """
    输出三角函数的latex公式,因为在sympy中对于具体弧度 sympy会直接进行计算
    :param trig_str:
    :return:
    >>> print_trig_latex('-2*sin(x + pi/5) + 3')
    -2\\sin (x + \\frac{\\pi}{5})+3
    """
    t_coef, t_type, t_arg, t_const = simp_trig_info(trig_str)
    t_format = r'%s\%s (%s)'
    if t_coef == 1:
        t_coef_latex = ''
    elif t_coef == -1:
        t_coef_latex = '- '
    else:
        t_coef_latex = new_latex(t_coef)
    t_mon_latex = t_format % (t_coef_latex, str(t_type), new_latex(t_arg))
    if t_const == 0:
        t_mon_latex = t_mon_latex
    elif t_const > 0:
        t_mon_latex = t_mon_latex + '+' + new_latex(t_const)
    else:
        t_mon_latex = t_mon_latex + new_latex(t_const)
    return t_mon_latex


def expr_value_list(e, var_interval):
    """
    表达式列表。在定义域内求表达式的值
    :param e:
    :param var_interval:
    :return:
    >>> expr_value_list('k*pi', Interval(-pi / 3, 5 * pi / 3))
    [0, pi]
    >>> expr_value_list('k', Interval(sympify('2'), sympify('3')))
    [2, 3]
    """
    e = sympify(e)
    if e.is_real:
        if e in S.Integers and e in var_interval:
            return [e, ]
        else:
            return []
    var_symbol = list(e.free_symbols)[0]
    left = var_interval.left
    right = var_interval.right

    def _values(_left, _right, _e):
        _start = ceiling(list(list(co.isolve_eq(BaseEq([_e - _left, '0'])).values())[0])[0])
        _end = floor(list(list(co.isolve_eq(BaseEq([_e - _right, '0'])).values())[0])[0])
        _inters = range(_start, _end + 1)
        return [_e.subs(var_symbol, _i) for _i in _inters]

    if left.is_real and right.is_real:
        values = _values(left, right, e)
        return filter(lambda _: _ in var_interval, values)
    else:
        _k = list(left.free_symbols)[0]
        last_values = []
        for k_value in range(-10, 10):
            tmp_left = left.subs(_k, k_value)
            tmp_right = right.subs(_k, k_value)
            last_values.extend(_values(tmp_left, tmp_right, e))
        last_values = filter(lambda _: _ in var_interval, last_values)
        return last_values


def trig_cycle(trig_f_type):
    """
    三角函数的周期
    :param trig_f_type: 
    :return: 
    >>> trig_cycle(sin)
    2*pi
    """
    if str(trig_f_type) in ['sin', 'cos']:
        return 2 * pi
    elif str(trig_f_type) in ['tan', 'cot']:
        return pi
    else:
        raise Exception('illegal trig type')


def get_quadrant_with_x_y(x_value, y_value):
    """
    根据x,y的值获取点所在象限
    :param x_value: 
    :param y_value: 
    :return: 
    """
    if x_value > 0 and y_value > 0:
        return 1
    elif x_value < 0 < y_value:
        return 2
    elif x_value < 0 and y_value < 0:
        return 3
    elif x_value > 0 > y_value:
        return 4
    else:
        return 0


def tirg_value_in_interval(trig_expr, trig_value, intl):
    """
    根据某个三角函数值 判断 是否有可能落在改区间内
    :param trig_expr: 
    :param trig_value:
    :param intl: 
    :return: 
    >>> tirg_value_in_interval(sin('x'), sympify('-1/2'), Interval(0, pi / 2))
    False
    >>> tirg_value_in_interval(cos('2*x + pi/3'), sympify('1/2'), Interval(0, pi / 2))
    True
    """
    trig_expr = sympify(trig_expr)
    x_symbol = list(trig_expr.free_symbols)[0]
    t_coef, t_type, t_arg, t_const = simp_trig_info(trig_expr)
    expr_t_sub = trig_expr.subs(t_arg, 't')
    from mathsolver.functions.sanjiao.sanjiaofangcheng import JieSanJiaoFangCheng
    t_results = list(JieSanJiaoFangCheng().solver(BaseEq([expr_t_sub, trig_value])).output[0].sympify().values()[0])
    x_results = map(lambda _: expand(solve(_ - sympify(t_arg), x_symbol)[0]), t_results)
    x_results = list(co.flatten(map(lambda _: expr_value_list(_, intl), x_results)))
    if x_results:
        return True
    else:
        return False


# print tirg_value_in_interval(sin('x'), sympify('1/2'), Interval(0, pi / 2))


def m_expr_2_s_expr(m_expr):
    """
    Mathematic中的表达式转换为sympy表达式
    :param m_expr: 
    :return: 
    """
    s_expr = sympify(m_expr)
    s_expr = s_expr.subs('Pi', pi).subs('C_1', 'k')
    return s_expr


def solve_trig_eq(trig_eq, x_symbol='x', symbol_interval=None):
    """
    解三角方程
    :param trig_eq: 
    :param x_symbol: 
    :param symbol_interval:
    :return: 
    >>> solve_trig_eq(BaseEq(['sin(x) - sqrt(3)/3', '0']))
    [2*pi*k + asin(sqrt(3)/3), 2*pi*k - asin(sqrt(3)/3) + pi]
    >>> solve_trig_eq(BaseEq(['x*cos(2*x)', '0']), symbol_interval=Interval(0, 2 * pi))
    [0, pi/4, 3*pi/4, 5*pi/4, 7*pi/4]
    """
    l, r = trig_eq.sympify()
    f = l - r
    symbs = list(f.free_symbols)
    if len(symbs) == 1:
        x_symbol = symbs[0]
    solve_set = list(JieSanJiaoFangCheng().solver(trig_eq, BaseVariable(x_symbol)).output[0].sympify().values()[0])
    if symbol_interval:  # 如果有区间
        last_seolve_set = []
        for v_expr in solve_set:
            if isinstance(symbol_interval, Interval):
                last_seolve_set.extend(expr_value_list(v_expr, symbol_interval))
                last_seolve_set = filter(lambda _: _ in symbol_interval, last_seolve_set)
            elif isinstance(symbol_interval, Union):
                for intl in symbol_interval.args:
                    last_seolve_set.extend(expr_value_list(v_expr, intl))
                last_seolve_set = filter(lambda _: _ in symbol_interval, last_seolve_set)
            else:
                raise Exception('Symbol\'s interval must be Interval or Union')
        return list(set(last_seolve_set))

    else:
        return solve_set


def maybe_in_interval(param_intl, intl):
    """
    给定一个具体的区间 和一个 区间集合 判断这个具体的区间有没有可能落在这个 区间集合上
    :param param_intl: 
    :param intl: 
    :return: 
    """

    def _single_in_interval(_param_intl, _intl):
        left = _param_intl.left
        left_open = _param_intl.left_open
        right = _param_intl.right
        right_open = _param_intl.right_open
        k_symbol = list(left.free_symbols)[0]
        k_range = range(-10, 10)
        for i in k_range:
            left_value = left.subs(k_symbol, i)
            right_value = right.subs(k_symbol, i)
            tmp_intl = Interval(left_value, right_value, left_open, right_open)
            if _intl.is_subset(tmp_intl):
                return True
        return False

    if isinstance(param_intl, Interval) and isinstance(intl, Interval):
        return _single_in_interval(param_intl, intl)
    elif isinstance(param_intl, Union) and isinstance(intl, Interval):
        for tmp_param_intl in param_intl.args:
            if _single_in_interval(tmp_param_intl, intl):
                return True
        return False


def sin_2_cos(sin_f):
    """
    sin转换为cos
    :param sin_f:
    :return:
    >>> sin_2_cos(sin('x'))
    (1, cos, x - pi/2, 0)
    >>> cos_2_sin('sin(x-pi/3)')
    (1, sin, x - pi/3, 0)
    >>> sin_2_cos(sin('x'))
    (1, cos, x - pi/2, 0)
    """
    sin_coef, _1, sin_arg, _2 = simp_trig_info(sin_f)
    if _1 == cos:
        return sin_coef, _1, sin_arg, _2
    cos_arg = sympify('pi/2') - sympify(sin_arg)
    cos_coef = sin_coef
    cos_arg_x_coef = cos_arg.coeff('x')
    if not cos_arg_x_coef.is_real:  # 如果x的系数是一个参数
        param_symb = list(cos_arg_x_coef.free_symbols)[0]
        cos_arg_x_coef = cos_arg_x_coef.coeff(param_symb)
    if cos_arg_x_coef < 0:
        cos_arg = -cos_arg
    return cos_coef, cos, cos_arg, _2


def cos_2_sin(cos_f):
    """
    cos转换为sin
    :param cos_f:
    :return:
    >>> cos_2_sin(cos('x'))
    (-1, sin, x - pi/2, 0)
    >>> cos_2_sin('-cos(x+pi/6)')
    (1, sin, x - pi/3, 0)
    """
    cos_coef, _1, cos_arg, _2 = simp_trig_info(cos_f)
    if _1 == sin:
        return cos_coef, _1, cos_arg, _2
    sin_arg = sympify('pi/2') - sympify(cos_arg)
    sin_coef = cos_coef
    sin_arg_x_coef = sin_arg.coeff('x')
    if not sin_arg_x_coef.is_real:  # 如果x的系数是一个参数
        param_symb = list(sin_arg_x_coef.free_symbols)[0]
        sin_arg_x_coef = sin_arg_x_coef.coeff(param_symb)
    if sin_arg_x_coef < 0:
        sin_arg = -sin_arg
        sin_coef = -sympify(sin_coef)
    return sin_coef, sin, sin_arg, _2


def tan_2_cot(tan_f):
    """
    tan转换为cot
    :param tan_f: 
    :return: 
    >>> tan_2_cot('tan(2*x - pi/3)')
    (-1, cot, 2*x + pi/6, 0)
    """
    t_coef, t_type, t_arg, t_const = simp_trig_info(tan_f)
    if t_type == cot:
        return t_coef, t_type, t_arg, t_const
    return -t_coef, cot, t_arg + pi / 2, t_const


def cot_2_tan(cot_f):
    """
    cot转换为tan
    :param cot_f: 
    :return: 
    >>> cot_2_tan('cot(2*x - pi/3)')
    (-1, tan, 2*x + pi/6, 0)
    """
    t_coef, t_type, t_arg, t_const = simp_trig_info(cot_f)
    if t_type == tan:
        return t_coef, t_type, t_arg, t_const
    return -t_coef, tan, t_arg + pi / 2, t_const


def convert_same_type_trig(f1, f2):
    """
    两个三角函数转换为同名的三角函数
    :param f1: 
    :param f2: 
    :return: 
    """
    t1_coef, t1_type, t1_arg, t1_c = simp_trig_info(f1)
    t2_coef, t2_type, t2_arg, t2_c = simp_trig_info(f2)
    if t1_type != t2_type:  # 首先转变成同名三角函数
        # 方式一都转变成sin函数
        t1_coef, t1_type, t1_arg, t1_c = cos_2_sin(f1)
        t2_coef, t2_type, t2_arg, t2_c = cos_2_sin(f2)
        if t1_coef * t2_coef < 0:  # 如果转变后两个不同号
            t1_coef, t1_type, t1_arg, t1_c = sin_2_cos(f1)
            t2_coef, t2_type, t2_arg, t2_c = sin_2_cos(f2)
    return t1_coef * t1_type(t1_arg) + t1_c, t2_coef * t2_type(t2_arg) + t2_c


def param_intl_intersect(p_intl1, p_intl2):
    """
    含参区间求交集
    :param p_intl1: 
    :param p_intl2: 
    :return: 
    """
    i1_l, i1_r = p_intl1.left, p_intl1.right
    i1_l_open, i1_r_open = p_intl1.left_open, p_intl1.right_open
    i2_l, i2_r = p_intl2.left, p_intl2.right
    i2_l_open, i2_r_open = p_intl2.left_open, p_intl2.right_open
    i1_l_const = co.split_mons_const(i1_l)[1]
    i1_r_const = co.split_mons_const(i1_r)[1]
    i2_l_const = co.split_mons_const(i2_l)[1]
    i2_r_const = co.split_mons_const(i2_r)[1]
    n_l = max([(i1_l, i1_l_const, i1_l_open), (i2_l, i2_l_const, i2_l_open)], key=itemgetter(1))
    n_r = min([(i1_r, i1_r_const, i1_r_open), (i2_r, i2_r_const, i2_r_open)], key=itemgetter(1))
    n_intl = Interval(n_l[0], n_r[0], left_open=n_l[-1], right_open=n_r[-1])
    return n_intl


def angle_expr_interval(angle_expr, angle_interval):
    """
    角表达式的取值范围
    :param angle_expr: 角的表达式
    :param angle_interval: 角的取值范围
    :return: 
    >>> angle_expr_interval('x/3 + pi/2', Interval(sympify('2*k*pi + 3*pi/2'), sympify('2*k*pi + 2*pi')))
    [2*pi*k/3 + pi, 2*pi*k/3 + 7*pi/6]
    """
    angle_expr = sympify(angle_expr)
    left = angle_interval.left
    left_open = angle_interval.left_open
    right_open = angle_interval.right_open
    right = angle_interval.right
    angle_symb = list(angle_expr.free_symbols)[0]
    coef = angle_expr.coeff(angle_symb)
    if coef < 0:
        left, right = right, left
        left_opem, right_open = right_open, left_open
    new_left = angle_expr.subs(angle_symb, left)
    new_right = angle_expr.subs(angle_symb, right)
    return Interval(new_left, new_right, left_open, right_open)


def angle_interval_quadrant(angle_interval):
    """
    给定角的区间，求角有可能存在的象限
    :param angle_interval: 
    :return: 
    >>> angle_interval_quadrant(Interval.open(sympify('2*k*pi + 3*pi/2'), sympify('2*k*pi + 2*pi')))
    [4]
    """
    from mathsolver.functions.sanjiao.Jiao import angle_interval_quad
    return angle_interval_quad(angle_interval)


def half_and_double_trig_values(trig_f_arg, sin_value, cos_value):
    """
    根据三角函数的的参数，求出其半角和二倍角的三角函数值
    :param trig_f_arg: 
    :param sin_value: 
    :param cos_value: 
    :return: 
    >>> half_and_double_trig_values('x', '1/2', 'sqrt(3)/2')
    ([[(sin(x/2), -sqrt(-sqrt(3) + 2)/2), (cos(x/2), -1/(2*sqrt(-sqrt(3) + 2))), (tan(x/2), 1), (cot(x/2), y/x)],
    [(sin(x/2), sqrt(-sqrt(3) + 2)/2), (cos(x/2), 1/(2*sqrt(-sqrt(3) + 2))), (tan(x/2), 1), (cot(x/2), y/x)]],
    [[sin(2*x), sqrt(3)/2], [cos(2*x), 1/2], [tan(2*x), sqrt(3)], [cot(2*x), sqrt(3)/3]])
    """
    t_arg = sympify(trig_f_arg)
    sin_value = sympify(sin_value)
    cos_value = sympify(cos_value)
    half_sin, half_cos = symbols('x, y')  # x 代表 sin(f/2); y代表cos(f/2)

    result_subs = (('x', sin(t_arg / 2)), ('y', cos(t_arg / 2)))
    eqs1 = [[2 * half_sin * half_cos, sin_value], [half_sin ** 2 + y ** 2, 1],
            [cos_value, 2 * half_cos ** 2 - 1]]
    half_trig_values = []
    symbols_values = co.isolve_eqs(BaseEqs(eqs1), [half_sin, half_cos])
    half_tan = sin(t_arg / 2) / cos(t_arg / 2)
    half_cot = cos(t_arg / 2) / sin(t_arg / 2)
    for symbols_value in symbols_values:
        trig_values = list(map(lambda _: (_[0].subs(result_subs), _[1].subs(result_subs)), symbols_value))
        half_tan_value = half_tan.subs(trig_values)
        half_cot_value = half_cot.subs(trig_values)
        trig_values.append((tan(t_arg / 2), half_tan_value))
        trig_values.append((cot(t_arg / 2), half_cot_value))
        half_trig_values.append(trig_values)
    x2_value = 2 * sin_value * cos_value  # sin(2*f)
    y2_value = 2 * cos_value ** 2 - 1  # cos(2*f)
    double_trig_values = [[sin(2 * t_arg), x2_value], [cos(2 * t_arg), y2_value],
                          [tan(2 * t_arg), x2_value / y2_value], [cot(2 * t_arg), y2_value / x2_value]]
    return half_trig_values, double_trig_values


def print_belong_z(symb):
    return new_latex(sympify(symb)) + ' \\in ' + new_latex(S.Integers)


def i_trig_simplify(trig_f):
    """
    自定义的三角函数化简
    :param trig_f: 
    :return: 
    """
    trig_f = sympify(trig_f)
    mo, de = co.complete_fraction(trig_f)
    from mathsolver.functions.sanjiao.huajian import trig_simplify
    mo_simp = simplify(mo)
    if str(mo).find('sin') >= 0 or str(mo).find('cos') >= 0 or str(mo).find('tan') >= 0 or str(mo).find('cot') >= 0:
        try:
            mo_simp = trig_simplify(mo)
        except Exception:
            pass
    de_simp = simplify(de)
    if str(de).find('sin') >= 0 or str(de).find('cos') >= 0 or str(de).find('tan') >= 0 or str(de).find('cot') >= 0:
        try:
            de_simp = trig_simplify(de)
        except Exception:
            pass
    return mo_simp / de_simp


def filter_quad_trig_values(trig_values_list, symb, quad):
    """
    过滤掉不满足角象限条件的三角函数值
    :param trig_values_list: 
    :param symb: 
    :param quad: 
    :return: 
    """
    symb = sympify(symb)
    new_values_list = []
    for values in trig_values_list:
        trig_values_map = dict(values)
        sin_v = trig_values_map[sin(symb)]
        sin_pm = Jiao.trig_f_quad_pm('sin')[quad - 1]
        cos_v = trig_values_map[cos(symb)]
        cos_pm = Jiao.trig_f_quad_pm('cos')[quad - 1]
        if sin_v * sin_pm > 0 and cos_v * cos_pm > 0:
            new_values_list.append(values)
    return new_values_list


def filter_interval_trig_values(trig_values_list, symb, interval):
    """
    过滤掉不满足变量区间范围的三角函数值
    :param trig_values_list: 
    :param symb: 
    :param interval: 
    :return: 
    """
    new_values_list = []
    for values in trig_values_list:
        trig_values_map = dict(values)
        sin_v = trig_values_map[sin(symb)]
        cos_v = trig_values_map[cos(symb)]
        if tirg_value_in_interval(sin(symb), sin_v, interval) \
                and tirg_value_in_interval(cos(symb), cos_v, interval):
            new_values_list.append(values)
    return new_values_list


def i_is_subset(iter1, iter2):
    """
    判断一个集合是否为另一个集合的子集
    :param iter1: 序列1
    :param iter2: 序列2
    :return: 
    >>> i_is_subset(symbols('a, b'), symbols('a,b,c'))
    True
    """
    iter1 = co.flatten([iter1])
    iter2 = co.flatten([iter2])
    s1 = set(iter1)
    s2 = set(iter2)
    return s1.issubset(s2)


if __name__ == '__main__':
    pass
